package com.kgcx.coupon.service;

import com.github.pagehelper.PageHelper;
import com.kgcx.common.bean.RequestData;
import com.kgcx.common.client.order.OrderClient;
import com.kgcx.common.client.organization.pojo.CustomerMsg;
import com.kgcx.common.client.price.PriceClient;
import com.kgcx.common.constant.Cons;
import com.kgcx.common.exception.BusinessException;
import com.kgcx.common.rabbitmq.producer.CustomerMsgProducer;
import com.kgcx.common.utils.CollectionUtils;
import com.kgcx.coupon.constant.CouponCode;
import com.kgcx.coupon.domain.Billing;
import com.kgcx.coupon.domain.BillingDeal;
import com.kgcx.coupon.domain.BillingDetail;
import com.kgcx.coupon.mapper.BillingDealMapper;
import com.kgcx.coupon.mapper.BillingDetailMapper;
import com.kgcx.coupon.mapper.BillingMapper;
import com.kgcx.dbutils.domain.BaseDomain;
import com.kgcx.dbutils.utils.PageUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.List;

@Service
@Slf4j
public class BillingService {
    @Autowired
    private BillingMapper billingMapper;

    @Autowired
    private OrderClient orderClient;

    @Autowired
    private BillingDetailMapper billingDetailMapper;

    @Autowired
    private BillingDealMapper billingDealMapper;

    @Autowired
    private CustomerMsgProducer customerMsgProducer;

    @Autowired
    private PriceClient priceClient;

    public Billing selectPrimaryKey(Long kid) {
        Billing billing = billingMapper.selectByPrimaryKey(kid);
        return billing;
    }


    public List<Billing> select(RequestData requestData) {
        PageUtils.page(requestData.getPageNum(), requestData.getPageSize());
        PageHelper.orderBy("order_time desc");
        List<Billing> list = billingMapper.selectActive(BaseDomain.buildSelectDomain(requestData, new Billing()));
        return list;
    }

    @Transactional(rollbackFor = Exception.class)
    public void deletePrimaryKey(Long kid) {
        billingMapper.deleteByPrimaryKey(kid);
    }


    @Transactional(rollbackFor = Exception.class)
    public void updatePrimaryKey(Billing billing) {
        billingMapper.updateByPrimaryKeySelective(billing);
    }


    //前台新增
    @Transactional(rollbackFor = Exception.class)
    public void addBilling(Billing billing) {

//        BigDecimal orderAmountData= new BigDecimal(10000);
        Long orderAmount = queryPaiedOrderAmount(billing.getUserId().longValue());
        //空指针判断

        Long billingAmount = billingMapper.getBillingAmount(billing.getUserId());
        if (null != billingAmount) {
            orderAmount = orderAmount - billingAmount;
        }
//            orderAmount = orderAmountData.intValue();

        Integer totalQty = 0;
        Integer totalMoney = 0;
        List<BillingDetail> detailList = billing.getDetailList();
        for (BillingDetail detail : detailList) {
            totalQty += detail.getBillingNumber();
            totalMoney += (detail.getMoney() * detail.getBillingNumber());
        }
        billing.setBillingNo(System.currentTimeMillis() + "");
        billing.setBillingNumber(totalQty);
        billing.setMoney(totalMoney);
        billing.setAmount(totalMoney);
        billing.setOrderStatus(BillingDeal.UN_APPROVE);
        billing.setOrderTime(new Timestamp(System.currentTimeMillis()));
        // 比较 订单金额与  totalMoney比较
        if (orderAmount.intValue() >= totalMoney) {
            //批量保存发票明细

            billingMapper.insertSelective(billing);

            for (BillingDetail detail : detailList) {
                //将发票主键存入发票明细billId
                detail.setBillId(billing.getKid());
                billingDetailMapper.insertSelective(detail);
            }


        } else {
            throw new BusinessException(CouponCode.BILLING_AMOUNT_LIMIT.getCode(), CouponCode.BILLING_AMOUNT_LIMIT.getMessage());
        }
    }

    public List<Billing> queryUserBilling(Integer userId, Integer pageNo, Integer pageSize) {
        PageUtils.page(pageNo, pageSize);
        PageHelper.orderBy("create_time desc");
        Billing billing = new Billing();
        billing.setUserId(userId);
        return billingMapper.select(billing);


    }

    public Long getUnBillingAmount(Integer userId) {
        Long orderAmount = queryPaiedOrderAmount(Long.valueOf(userId));


        Long billingNum = billingMapper.getBillingAmount(userId);
        if (null == billingNum) {
            billingNum = 0L;
        }
        return orderAmount - billingNum;


    }

    private Long queryPaiedOrderAmount(Long userId) {
        List<String> list = orderClient.queryPaiedOrderList(userId);
        if (CollectionUtils.isNotEmpty(list)) {
            Long totalPriceByOrderId = priceClient.getTotalPriceByOrderId(list);
            if (null != totalPriceByOrderId) {
                return totalPriceByOrderId;
            }
        }
        return 0L;

    }

    @Transactional(rollbackFor = Exception.class)
    public void approveBilling(Long billingId, Long userId) {
        Billing billing = selectPrimaryKey(billingId);
        if (null != billing) {
            billing.setOrderStatus(BillingDeal.APPROVE);
            billingMapper.updateByPrimaryKeySelective(billing);

            BillingDeal billingDeal = BaseDomain.getInstance(BillingDeal.class);
            billingDeal.setBillingId(billingId);
            billingDeal.setUserId(userId);
            billingDeal.setAction(BillingDeal.APPROVE.toString());
            billingDealMapper.insertSelective(billingDeal);

            CustomerMsg customerMsg = new CustomerMsg();
            customerMsg.setCustomerId(billing.getUserId().longValue());
            customerMsg.setTypeId(1);
            customerMsg.setIsRead(CustomerMsg.UNREAD);
            customerMsg.setTitle("开票提醒");
            customerMsg.setContent("您于" + DateFormatUtils.format(billing.getOrderTime(), Cons.DATE_FORMAT_YYYY_MM_DD_HH_MM_SS) + "提交的开票申请已审核通过,快递单号可在开票历史中查询.");
            customerMsgProducer.customerMsgSend(customerMsg);

        } else {
            throw new BusinessException(CouponCode.BILLING_NOT_EXISTS.getCode(), CouponCode.BILLING_NOT_EXISTS.getMessage());
        }


    }

    @Transactional(rollbackFor = Exception.class)
    public void billing(Long billingId, Long userId) {
        Billing billing = selectPrimaryKey(billingId);
        if (null != billing) {
            billing.setOrderStatus(BillingDeal.BILLING);
            billingMapper.updateByPrimaryKeySelective(billing);

            BillingDeal billingDeal = BaseDomain.getInstance(BillingDeal.class);
            billingDeal.setBillingId(billingId);
            billingDeal.setUserId(userId);
            billingDeal.setAction(BillingDeal.BILLING.toString());
            billingDealMapper.insertSelective(billingDeal);

        } else {
            throw new BusinessException(CouponCode.BILLING_NOT_EXISTS.getCode(), CouponCode.BILLING_NOT_EXISTS.getMessage());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void send(Long billingId, Long userId, String mailNumber) {
        Billing billing = selectPrimaryKey(billingId);
        if (null != billing) {
            billing.setOrderStatus(BillingDeal.SEND);
            billing.setMailNumber(mailNumber);
            billingMapper.updateByPrimaryKeySelective(billing);

            BillingDeal billingDeal = BaseDomain.getInstance(BillingDeal.class);
            billingDeal.setBillingId(billingId);
            billingDeal.setUserId(userId);
            billingDeal.setAction(BillingDeal.SEND.toString());
            billingDealMapper.insertSelective(billingDeal);

        } else {
            throw new BusinessException(CouponCode.BILLING_NOT_EXISTS.getCode(), CouponCode.BILLING_NOT_EXISTS.getMessage());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void refuse(Long billingId, Long userId) {
        Billing billing = selectPrimaryKey(billingId);
        if (null != billing) {
            billing.setOrderStatus(BillingDeal.REFUSE);
            billingMapper.updateByPrimaryKeySelective(billing);

            BillingDeal billingDeal = BaseDomain.getInstance(BillingDeal.class);
            billingDeal.setBillingId(billingId);
            billingDeal.setUserId(userId);
            billingDeal.setAction(BillingDeal.REFUSE.toString());
            billingDealMapper.insertSelective(billingDeal);

        } else {
            throw new BusinessException(CouponCode.BILLING_NOT_EXISTS.getCode(), CouponCode.BILLING_NOT_EXISTS.getMessage());
        }
    }


}
